<?php
/**
 * Created by PhpStorm.
 * User: tangsian
 * Date: 2021/1/7
 * Time: 10:44
 */

namespace App\Http\Model\Api;


use App\Http\Model\Base;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

class RoomDurationRecord extends Base
{
    protected $table = 'room_duration_record';
    protected $connection = "mysql_kkaudio";
    protected $primaryKey = 'id';
    protected $redis_cache_sound_byte_room_duration_rank = 'CACHE:SOUND_BYTE:ROOM_DURATION_RANK:LIST';
    protected $redis_cache_sound_byte_room_duration_yuan_rank = 'CACHE:SOUND_BYTE:ROOM_DURATION_RANK:YUAN_LIST';
    protected $redis_cache_sound_byte_room_duration_visit = 'CACHE:SOUND_BYTE:ROOM_DURATION_RANK_VISIT:LIST';
    protected $cacheRedisKeyRoomDurationSuspendTime = 'CACHE:SOUND_BYTE:ROOM_DURATION_RANK:SUSPEND_TIME';
    protected $cacheRedisKeyAdvancedRoomDurationList = 'CACHE:SOUND_BYTE:ADVANCE_ROOM_DURATION_LIST';
    protected $cacheRedisKeyTimeStep = 'CACHE:SOUND_BYTE:ROOM_DURATION:TIME_STEP';
    protected $timesArray = [
        0 => [
            'start_time' => 1608793404,
            'end_time' => 1608825600
        ],
        1 => [
            'start_time' => 1608825600,
            'end_time' => 1608912000
        ],
        2 => [
            'start_time' => 1608912000,
            'end_time' => 1608998400
        ],
    ];

    public function __construct(array $attributes = [])
    {
        parent::__construct($this->table, $attributes);
    }

    /**
     * 房间在线时长列表数量排行
     * @param $condition
     * @param $limit
     * @param $userIds
     * @param $endTime
     * @param $startTime
     * @return int
     */
    public function set_room_duration_count_rank($condition, $limit, $startTime, $endTime, array $userIds = [])
    {
        $db = DB::connection($this->connection)->table($this->table);

        if (!empty($condition)) {
            $db->where($condition);
        }

        if (empty($startTime)) {
            $startTime = 0;
        }

        if (empty($endTime)) {
            $endTime = time();
        }
        $db->leftJoin('room','room.room_id','=',$this->table.'.room_id');
        $db->where($this->table.'.type','=',1);
        $db->where('room.business_type','=',0);
        $db->whereBetween($this->table.'.created_at', [$startTime, $endTime]);

        if (!empty($userIds) && is_array($userIds)) {
            $db->whereIn($this->table.'.user_id', $userIds);
        }

        $db->select(DB::raw('SUM(duration_time) as total_num,zb_room_duration_record.user_id as user_id'));
        $db->groupBy($this->table.'.user_id');

        $result = self::objToArray($db->orderBy('total_num', 'desc')->limit($limit)->get()->toArray());

        foreach ($result as $val) {
            Redis::Zadd($this->redis_cache_sound_byte_room_duration_rank . '_' . $startTime . '_' . $endTime, intval($val['total_num']), $val['user_id']);
        }

        Redis::EXPIRE($this->redis_cache_sound_byte_room_duration_rank . '_' . $startTime . '_' . $endTime, 300);

        return array_column($result, 'total_num', 'user_id');
    }

    /**
     * 获取当前阶段的排行数据
     * @return array
     */
    public function get_step_room_duration_count_rank()
    {
        //获取当前前百名阶段
        $timeStep = intval(Redis::get($this->cacheRedisKeyTimeStep));
        if (Redis::Exists($this->cacheRedisKeyRoomDurationSuspendTime)) {
            $timeStep -= 1;
        }

        if (Redis::exists($this->redis_cache_sound_byte_room_duration_rank . '_' . $this->timesArray[$timeStep]['start_time'] . '_' . $this->timesArray[$timeStep]['end_time'])) {
            return Redis::Zrevrange($this->redis_cache_sound_byte_room_duration_rank . '_' . $this->timesArray[$timeStep]['start_time'] . '_' . $this->timesArray[$timeStep]['end_time'], 0, -1, 'WITHSCORES');
        }

        return [];
    }

    /**
     * 获取上阶段累计排行数据
     * @return array
     */
    public function get_yuan_room_duration_count_rank()
    {
        if (intval(Redis::get($this->cacheRedisKeyTimeStep)) > 0 && !Redis::Exists($this->cacheRedisKeyRoomDurationSuspendTime)) {
            return Redis::Zrevrange($this->redis_cache_sound_byte_room_duration_yuan_rank, 0, -1, 'WITHSCORES');
        }
        return [];
    }

    /**
     * 获取当前阶段的时间数据
     * @param $timeStep
     * @return mixed
     */
    public function getTimeStepTimeArray($timeStep = 0)
    {
        return $this->timesArray[$timeStep];
    }

    public function getTimeStep()
    {
        return intval(Redis::get($this->cacheRedisKeyTimeStep));
    }

    /**
     * 校验是否是在比赛期间
     * @return bool
     */
    public function checkIsInTimeArr()
    {
        $result = false;
        foreach ($this->timesArray as $val) {
            if (time() >= $val['start_time'] && time() < $val['end_time']) {
                $result = true;
                break;
            }
        }

        return $result;
    }

    /**
     * 设置暂停时间并添加上阶段数据
     * @param $data
     */
    public function setInSuspendTimeData($data)
    {
        foreach ($data as $key => $val) {
            Redis::Zadd($this->redis_cache_sound_byte_room_duration_yuan_rank, $val, $key);
        }

        $timeStep = intval(Redis::get($this->cacheRedisKeyTimeStep));
        Redis::setex($this->cacheRedisKeyTimeStep, 86400, intval($timeStep + 1));
    }

    /**
     * 获取进阶人员数组集合
     * @return mixed
     */
    public function getAdvancedRoomDurationList()
    {
        return Redis::Smembers($this->cacheRedisKeyAdvancedRoomDurationList);
    }

    /**
     * 获取用户的分数
     * @param $userId
     * @return int
     */
    public function getUserRoomDurationRank($userId, $startTime, $endTime)
    {

        if (Redis::Exists($this->redis_cache_sound_byte_room_duration_visit, $userId)) {
            $score = Redis::Zscore($this->redis_cache_sound_byte_room_duration_visit, $userId);
            return [$userId => $score];
        }
        $db = DB::connection($this->connection)->table($this->table);

        if (empty($startTime)) {
            $startTime = 0;
        }

        if (empty($endTime)) {
            $endTime = time();
        }

        $db->leftJoin('room','room.room_id','=',$this->table.'.room_id');
        $db->where($this->table.'.type','=',1);
        $db->whereBetween($this->table.'.created_at', [$startTime, $endTime]);

        if (!empty($userIds) && is_array($userIds)) {
            $db->whereIn($this->table.'.user_id', $userIds);
        }

        $db->select(DB::raw('SUM(duration_time) as total_num,room_duration_record.send_user_id as user_id'));
        $db->where('room.business_type','=',0);
        $result = self::objToArray($db->orderBy('total_num', 'desc')->get()->toArray());

        $score = 0;
        if (!empty($result[0]['total_num'])) {
            $score = $result[0]['total_num'];
        }

        Redis::Zadd($this->redis_cache_sound_byte_room_duration_visit, $score, $userId);
        if (Redis::Ttl($this->redis_cache_sound_byte_room_duration_visit) == -1) {
            Redis::Expire($this->redis_cache_sound_byte_room_duration_visit, 180);
        }
        return array_column($result, 'total_num', 'user_id');
    }

    public function setAdvancedRoomDurationList($data)
    {
        Redis::del($this->cacheRedisKeyAdvancedRoomDurationList);
        foreach ($data as $key => $val) {
            Redis::Sadd($this->cacheRedisKeyAdvancedRoomDurationList, $val);
        }
    }
}
